"""
时区工具模块
提供统一的时区处理功能
"""
import pytz
from datetime import datetime, timezone, timedelta
from typing import Optional


# 定义项目默认时区为东8区（中国标准时间）
DEFAULT_TIMEZONE = pytz.timezone('Asia/Shanghai')
UTC_TIMEZONE = pytz.UTC


def get_current_time(tz: Optional[pytz.BaseTzInfo] = None) -> datetime:
    """
    获取当前时间
    
    Args:
        tz: 时区，默认为项目默认时区（东8区）
        
    Returns:
        带时区信息的当前时间
    """
    if tz is None:
        tz = DEFAULT_TIMEZONE
    
    return datetime.now(tz)


def get_utc_time() -> datetime:
    """
    获取UTC时间
    
    Returns:
        UTC时间
    """
    return datetime.now(UTC_TIMEZONE)


def convert_to_local_time(utc_time: datetime, tz: Optional[pytz.BaseTzInfo] = None) -> datetime:
    """
    将UTC时间转换为本地时间
    
    Args:
        utc_time: UTC时间
        tz: 目标时区，默认为项目默认时区
        
    Returns:
        转换后的本地时间
    """
    if tz is None:
        tz = DEFAULT_TIMEZONE
    
    if utc_time.tzinfo is None:
        # 如果没有时区信息，假设为UTC
        utc_time = UTC_TIMEZONE.localize(utc_time)
    elif utc_time.tzinfo != UTC_TIMEZONE:
        # 如果不是UTC时区，先转换为UTC
        utc_time = utc_time.astimezone(UTC_TIMEZONE)
    
    return utc_time.astimezone(tz)


def convert_to_utc(local_time: datetime, from_tz: Optional[pytz.BaseTzInfo] = None) -> datetime:
    """
    将本地时间转换为UTC时间
    
    Args:
        local_time: 本地时间
        from_tz: 源时区，默认为项目默认时区
        
    Returns:
        UTC时间
    """
    if from_tz is None:
        from_tz = DEFAULT_TIMEZONE
    
    if local_time.tzinfo is None:
        # 如果没有时区信息，添加源时区
        local_time = from_tz.localize(local_time)
    
    return local_time.astimezone(UTC_TIMEZONE)


def naive_to_aware(naive_datetime: datetime, tz: Optional[pytz.BaseTzInfo] = None) -> datetime:
    """
    将naive datetime转换为aware datetime
    
    Args:
        naive_datetime: 没有时区信息的datetime
        tz: 时区，默认为项目默认时区
        
    Returns:
        带时区信息的datetime
    """
    if tz is None:
        tz = DEFAULT_TIMEZONE
    
    if naive_datetime.tzinfo is not None:
        return naive_datetime
    
    return tz.localize(naive_datetime)


def aware_to_naive(aware_datetime: datetime, tz: Optional[pytz.BaseTzInfo] = None) -> datetime:
    """
    将aware datetime转换为指定时区的naive datetime
    
    Args:
        aware_datetime: 带时区信息的datetime
        tz: 目标时区，默认为项目默认时区
        
    Returns:
        指定时区的naive datetime
    """
    if tz is None:
        tz = DEFAULT_TIMEZONE
    
    if aware_datetime.tzinfo is None:
        return aware_datetime
    
    local_time = aware_datetime.astimezone(tz)
    return local_time.replace(tzinfo=None)


def format_datetime(dt: datetime, format_str: str = '%Y-%m-%d %H:%M:%S', 
                   to_tz: Optional[pytz.BaseTzInfo] = None) -> str:
    """
    格式化datetime为字符串
    
    Args:
        dt: datetime对象
        format_str: 格式字符串
        to_tz: 目标时区，默认为项目默认时区
        
    Returns:
        格式化后的时间字符串
    """
    if to_tz is None:
        to_tz = DEFAULT_TIMEZONE
    
    if dt.tzinfo is None:
        # 如果是naive datetime，假设为默认时区
        dt = DEFAULT_TIMEZONE.localize(dt)
    
    local_dt = dt.astimezone(to_tz)
    return local_dt.strftime(format_str)


def get_timezone_offset(tz: Optional[pytz.BaseTzInfo] = None) -> str:
    """
    获取时区偏移量字符串
    
    Args:
        tz: 时区，默认为项目默认时区
        
    Returns:
        时区偏移量字符串，如 '+08:00'
    """
    if tz is None:
        tz = DEFAULT_TIMEZONE
    
    now = datetime.now(tz)
    offset = now.strftime('%z')
    # 格式化为 +08:00 的形式
    if len(offset) == 5:
        return f"{offset[:3]}:{offset[3:]}"
    return offset


def is_dst(dt: Optional[datetime] = None, tz: Optional[pytz.BaseTzInfo] = None) -> bool:
    """
    检查指定时间是否为夏令时
    
    Args:
        dt: 要检查的时间，默认为当前时间
        tz: 时区，默认为项目默认时区
        
    Returns:
        是否为夏令时
    """
    if tz is None:
        tz = DEFAULT_TIMEZONE
    
    if dt is None:
        dt = datetime.now(tz)
    elif dt.tzinfo is None:
        dt = tz.localize(dt)
    else:
        dt = dt.astimezone(tz)
    
    return bool(dt.dst())


# 为了向后兼容，提供一个替代datetime.utcnow()的函数
def utcnow() -> datetime:
    """
    获取当前UTC时间的naive datetime
    用于替代datetime.utcnow()，保持API兼容性
    
    Returns:
        UTC时间的naive datetime
    """
    return datetime.now(UTC_TIMEZONE).replace(tzinfo=None)


def now() -> datetime:
    """
    获取当前本地时间的aware datetime
    
    Returns:
        本地时间的aware datetime
    """
    return datetime.now(DEFAULT_TIMEZONE)